/** In-memory implementation of Repository. The type 
 *  parameter allows for the storage of any object marked 
 *  as Persistable
 *
 *  @author Scott Monahan
 *  @version $Id$
 *  
 *  File last changed on $Date:$ by $Author:$ in $Rev:$
 *
 */

package info637.pprc.repository;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

public abstract class AbstractListBasedRepository<T extends AbstractEntity, F extends IFilter<T>>
	implements IRepository<T, F> {

	static Logger log = Logger.getLogger(AbstractListBasedRepository.class.getName());
	
	private List<T> storage = new ArrayList<T>();

	@Override
	public boolean add(T toAdd) {
		
		boolean retVal = false;
		
		synchronized (this.storage) {
			
			retVal = false;
			
			toAdd.setId(Long.toString(System.currentTimeMillis()));
			
			log.debug("Adding new entity with ID: [" + toAdd.getId() + "]");
			
			retVal = storage.add(toAdd);
		}
		
		return retVal;
	}
	
	@Override
	public List<T> fetchAll() {
		
		synchronized (this.storage) {
			
			return this.storage;
		}
	}
	
	@Override
	public List<T> fetch(F filter) {
		
		synchronized (this.storage) {
			
			if (filter != null) {
	
				List<T> filteredList = new ArrayList<T>();
	
				for (T data : storage) {
	
					if (filter.matches(data)) {
	
						filteredList.add(data);
					}
				}
	
				return filteredList;
	
			} else {
	
				return storage;
			}
		}
	}
	
	@Override
	public boolean update(T oldVal, T newVal) {
		
		boolean retVal = false;
		
		synchronized (this.storage) {
			
			retVal = false;
			
			if (oldVal.getId().equalsIgnoreCase(newVal.getId())) {
				
				for (T row : this.storage) {
					
					if (row.getId().equalsIgnoreCase(oldVal.getId())) {
						
						this.storage.remove(row);
						
						retVal = this.storage.add(newVal);
						
						break;
					}
				}
			}
		}
		
		return retVal;
	}
	
	@Override
	public void delete(T toDelete) {
		
		synchronized (this.storage) {
			
			for (T row : this.storage) {
				
				if (row.getId().equalsIgnoreCase(toDelete.getId())) {
					
					this.storage.remove(row);
				}
			}
		}
	}
}
